package com.hpsk.swagger.shejimoshi.sign;

import com.hpsk.common.RespResult;
import com.hpsk.common.RespUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.security.*;
import java.util.Base64;

@Tag(name = "RSA加密")
@RestController
@RequestMapping("/swagger/rsa")
@Slf4j
public class RSAController {
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    @Operation(summary = "RSA加密测试")
    public RespResult<String> test() throws Exception {
        String value = "mrbird's blog";
        // 非对称加密算法
        String algorithm = "RSA";
        // 签名算法，RSA+SHA
        String signAlgorithm = "SHA256withRSA";

        // ----- 公私钥生成 --------
        // 实例化秘钥对生成器
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        // 初始化，秘钥长度512~16384位，64倍数
        keyPairGenerator.initialize(512);
        // 生成秘钥对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        // 公钥
        PublicKey publicKey = keyPair.getPublic();
        log.info("RSA公钥: {}", Base64.getEncoder().encodeToString(publicKey.getEncoded()));
        // 私钥
        PrivateKey privateKey = keyPair.getPrivate();
        log.info("RSA私钥: {}", Base64.getEncoder().encodeToString(privateKey.getEncoded()));

        // ----- 私钥加签 ---------
        // 获取签名对象
        Signature signature = Signature.getInstance(signAlgorithm);
        signature.initSign(privateKey);
        signature.update(value.getBytes());
        byte[] sign = signature.sign();
        log.info("签名值: {}", Base64.getEncoder().encodeToString(sign));

        // ----- 公钥验签 ---------
        signature.initVerify(publicKey);
        signature.update(value.getBytes());
        log.info("验签结果: [{}]", signature.verify(sign));
        return RespUtils.ok();
    }
}
